/*
Automatic clinic tests using a robot arm.
Copyright (C) 2010  CIC-CPC, CHU Gabriel Montpied
All other trademarks, logos and copyrights are the property
of their respective owners.

This file is part of cpc-painbot.

cpc-painbot is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

cpc-painbot is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with cpc-painbot.  If not, see <http://www.gnu.org/licenses/>.
*/
#include "Pilotableserie.h"

#include <QDebug>

#include "qserialdevice/abstractserial.h"

#include "commande/commande.h"

PilotableSerie::PilotableSerie(QObject * parent)
:Pilotable(parent),
serie_(new AbstractSerial(this))
{
    connect(serie_, SIGNAL(readyRead()), this, SLOT(lireDonnees()));
}

PilotableSerie::~PilotableSerie()
{
    connecter(false);
}

void PilotableSerie::connecter(bool on)
{
    //qDebug() << "PilotableSerie::connecter" << on;

    if ( serie_->isOpen() ) {
        serie_->flush();
        serie_->reset();
        serie_->close();
    }

    if ( on ) {
        bool ok = serie_->open(AbstractSerial::ReadWrite);
        if ( ok )
            configurerLiaison();
        else {
            qDebug() << "Impossible de se connecter.";
        }
    }
}

QString PilotableSerie::port() const
{
    return serie_->deviceName();
}

void PilotableSerie::connecter()
{
    connecter(true);
}

void PilotableSerie::deconnecter()
{
    connecter(false);
}

void PilotableSerie::setPort(const QString &port)
{
    if ( !serie_->isOpen() )
        serie_->setDeviceName(port);
}

void PilotableSerie::envoyer(const commande::Commande *cmd)
{
    serie_->write(cmd->generer().toAscii());
}

void PilotableSerie::lireDonnees()
{
    buffer_.append(serie_->read(serie_->bytesAvailable()));

    while ( !buffer_.isEmpty() && hasCommande() )
        parserCommande();
}

void PilotableSerie::configurerLiaison()
{
    // Définition de paramètres courants par défaut:
    // - 8 bits de données.
    // - 1 bit de stop.
    // - Contrôle de flux Off.
    // - Pas de parité.
    serie_->setDataBits(AbstractSerial::DataBits8);
    serie_->setStopBits(AbstractSerial::StopBits1);
    serie_->setFlowControl(AbstractSerial::FlowControlOff);
    serie_->setParity(AbstractSerial::ParityNone);
}
